package com.dymedia.aibo.mvp.model;

import com.dymedia.aibo.mvp.model.Entity.ChannelHeader;
import com.dymedia.aibo.mvp.model.Entity.Channel;
import com.dymedia.aibo.mvp.model.Entity.Client;
import com.dymedia.aibo.mvp.model.Entity.Group;
import com.dymedia.aibo.mvp.model.Entity.GroupHeader;
import com.dymedia.aibo.mvp.model.Entity.Video;
import com.dymedia.aibo.mvp.model.Entity.VideoHeader;
import com.dymedia.aibo.mvp.model.api.Api;
import com.dymedia.aibo.mvp.model.api.Cache;

import java.util.List;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Function;
import io.rx_cache2.DynamicKey;
import io.rx_cache2.EvictDynamicKey;
import me.jessyan.art.mvp.IModel;
import me.jessyan.art.mvp.IRepositoryManager;
import okhttp3.RequestBody;

/**
 * 必须实现 IModel
 * 可以根据不同的业务逻辑划分多个 Repository 类,多个业务逻辑相近的页面可以使用同一个 Repository 类
 * 无需每个页面都创建一个独立的 Repository
 * 通过 {@link me.jessyan.art.mvp.IRepositoryManager#createRepository(java.lang.Class)} 获得的 Repository 实例,为单例对象
 */
public class Repository implements IModel {
    private IRepositoryManager mManager;

    public Repository(IRepositoryManager manager) {
        this.mManager = manager;
    }

    public Observable<Client> setClient(String uid, RequestBody body){
        return mManager.createRetrofitService(Api.class)
                .setClient(uid, body);
    }

    public Observable<ChannelHeader> getChannels(Integer type, Integer limit, String code, int lastIdQueried, boolean update){
        return Observable.just(mManager
                .createRetrofitService(Api.class)
                .getChannels(type, limit, code))
                .flatMap((Function<Observable<ChannelHeader>, ObservableSource<ChannelHeader>>) listObservable -> mManager.createCacheService(Cache.class)
                        .getChannels(listObservable
                                , new DynamicKey(lastIdQueried)
                                , new EvictDynamicKey(update))
                        .map(listReply -> listReply.getData()));
    }

    public Observable<List<Channel>> getChannels(String mac){
        return mManager.createRetrofitService(Api.class)
                .getChannels(mac);
    }
    public Observable<List<Channel>> getChannelsHUB(String mac){
        return mManager.createRetrofitService(Api.class)
                .getChannelsHUB(mac);
    }
    public Observable<List<Channel>> getChannelsHUBTV(String mac){
        return mManager.createRetrofitService(Api.class)
                .getChannelsHUBTV(mac);
    }
    public Observable<List<Channel>> getChannelsAsia(String mac){
        return mManager.createRetrofitService(Api.class)
                .getChannelsASIA(mac);
    }
    public Observable<VideoHeader> getVideos(Integer type, Integer limit, String code, int lastIdQueried, boolean update){
        return Observable.just(mManager
                .createRetrofitService(Api.class)
                .getVideos(type, limit, code))
                .flatMap((Function<Observable<VideoHeader>, ObservableSource<VideoHeader>>) listObservable -> mManager.createCacheService(Cache.class)
                        .getVideos(listObservable, new DynamicKey(lastIdQueried), new EvictDynamicKey(update))
                        .map(listReply -> listReply.getData()));
    }

    public Observable<GroupHeader> getGroups(String type, String code, int lastIdQueried, boolean update){
        return Observable.just(mManager
                .createRetrofitService(Api.class)
                .getGroups(type, code))
                .flatMap((Function<Observable<GroupHeader>, ObservableSource<GroupHeader>>) listObservable -> mManager.createCacheService(Cache.class)
                        .getGroups(listObservable, new DynamicKey(type+lastIdQueried), new EvictDynamicKey(update))
                        .map(listReply -> listReply.getData()));
    }

    public Observable<Client> activeVip(String uid, String code, String cid){
        return mManager.createRetrofitService(Api.class)
                .activeVip(uid, code, cid);
    }

    @Override
    public void onDestroy() {

    }
}
